import { CreateUserDto } from './dto/create-user.dto';
import { User, UserRoles } from './user.entity';
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, Like, In, getConnection } from 'typeorm';
import { ResponseData } from '../../common/interfaces/result.interface';
import { CryptoUtil } from '../../common/utils/crypto.util';
import { JwtService } from '@nestjs/jwt';
import { resError, resSuccess } from '../../common/utils/response.util';
import { Role } from '../role/role.entity';
import moment = require('moment');

interface userRole {
  userId: number;
  username: string;
  roles: string[];
}

@Injectable()
export class UserService {
  constructor(
    @InjectRepository(User) private readonly userRepository: Repository<User>,
    @InjectRepository(Role) private readonly roleRepository: Repository<Role>,
    private readonly cryptoUtil: CryptoUtil,
    private readonly jwtService: JwtService,
  ) {}

  async findList({
    pageSize = 10,
    page = 1,
    id,
    username,
    nickname,
    status = 1,
  }): Promise<ResponseData> {
    interface whereInter {
      id?: number;
      username?: any;
      nickname?: any;
      status?: number;
    }
    const where: whereInter = {
      status: status,
    };
    id && (where.id = id);
    username && (where.username = Like(`%${username}%`));
    nickname && (where.nickname = Like(`%${nickname}%`));
    console.log('where', where);
    const [result, total] = await this.userRepository.findAndCount({
      select: [
        'id',
        'nickname',
        'username',
        'mobile',
        'createDate',
        'updateDate',
        'status',
      ],
      where,
      order: {
        createDate: 'DESC',
      },
      skip: (page - 1) * pageSize,
      take: pageSize,
    });
    // const user = this.userRepository.createQueryBuilder()
    // user.where('1 = 1')

    // const [result, total] = await user
    //   .where(where)
    //   .orderBy({
    //     create_date: 'DESC',
    //   })
    //   .skip(pageSize * (pageNum - 1))
    //   .take(pageSize)
    //   // .printSql()
    //   .getManyAndCount()

    // console.log('time', moment().subtract(1, 's').fromNow())
    return resSuccess('查询成功', {
      items: result.map((item) => {
        return {
          ...item,
          createDate: moment(item.createDate).format('YYYY-MM-DD HH:mm'),
          updateDate: moment(item.updateDate).format('YYYY-MM-DD HH:mm'),
        };
      }),
      total,
    });
  }

  async getUser(id: number) {
    const user = await this.userRepository.findOne({
      select: ['id', 'username'],
      where: { id },
      relations: ['roles'],
    });
    return resSuccess('查询成功', {
      userId: user.id,
      username: user.username,
      roles:
        user.roles.length > 0
          ? user.roles.map((role) => {
              return role.name;
            })
          : [],
    });
  }

  async getUserRole(id: number): Promise<ResponseData> {
    const userrole = await this.userRepository.findOne({
      select: ['id'],
      where: { id },
      relations: ['roles'],
    });
    const allrole = await this.roleRepository.find({
      select: ['id', 'title'],
    });
    return resSuccess('查询成功', {
      userId: userrole.id,
      roles: userrole.roles.map((item) => {
        return item.id;
      }),
      allrole,
    });
  }

  async setUserData(data): Promise<ResponseData> {
    // const user = await this.userRepository.findOne(data.id)
    // const newdata = Object.assign(user, data)
    const setuser = await this.userRepository.update(
      { id: data.id },
      { status: data.status },
    );
    if (setuser.affected) return resSuccess('修改成功', { ...setuser });
  }

  async validateUser(username: string, password: string): Promise<userRole> {
    const user = await this.userRepository.findOne({
      select: ['id', 'username', 'password'],
      where: { username },
      relations: ['roles'],
    });
    if (!user) return null;
    if (user.password !== this.cryptoUtil.encryptPassword(password))
      return null;
    return {
      userId: user.id,
      username: user.username,
      roles:
        user.roles.length > 0
          ? user.roles.map((role) => {
              return role.name;
            })
          : [],
    };
  }

  async create(dto: CreateUserDto): Promise<ResponseData> {
    let userdata = new User();
    dto.password = this.cryptoUtil.encryptPassword(dto.password);
    userdata = { ...dto, ...userdata };
    let result;
    let errorcode = 0,
      errmessage = '';
    try {
      result = await this.userRepository.save(userdata);
    } catch (error) {
      errorcode = error.errno;
      errmessage = error.sqlMessage;
    }
    if (errorcode) return resError(errorcode, errmessage);
    return resSuccess('注册成功', result);
  }

  async login(user: any): Promise<ResponseData> {
    const res = resSuccess('登录成功', {
      token: this.jwtService.sign(user),
      userId: user.userId,
      roles: user.roles,
    });
    return res;
  }

  async setUserRole(userId: number, role: string[]): Promise<ResponseData> {
    // const roleids = role.split(',')
    const where = {
      id: In(role),
    };
    const roleresult = await this.roleRepository.find({ where });
    const find = await this.userRepository.findOne({ id: userId });
    find.roles = roleresult;
    await this.userRepository.save(find);
    return resSuccess('用户角色关联成功');
  }

  async resetPassword(id: number, password = '123456'): Promise<ResponseData> {
    password = this.cryptoUtil.encryptPassword(password);
    await this.userRepository.update(id, {
      password,
    });
    return resSuccess('密码重置成功');
  }

  async delete(id: number): Promise<ResponseData> {
    const result = await this.userRepository.delete({ id });
    if (result.affected) {
      return resSuccess('删除成功');
    } else {
      return resError(500, '删除失败');
    }
  }
}
